﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using Core.Settings;
using System.Runtime.Serialization;
//using HtmlAgilityPack;

namespace Settings.Forms
{
//    using HtmlDocument = HtmlAgilityPack.HtmlDocument;
    public partial class SettingsForm : Form
    {
        private const string Default = "Default_aspx.htm";
        private const string Placowka = "Placowka_aspx.htm";
        private const string RejestracjaTerminu = "RejestracjaTerminu_aspx.htm";
        private const string FormularzWiza_2 = "FormularzWiza_2_aspx.htm";

        private static readonly KeyValuePair<string, KnownPage>[] PageNames = new[] {
            new KeyValuePair<string, KnownPage>(GetPageFullName(SettingsForm.Default), KnownPage.Default),
            new KeyValuePair<string, KnownPage>(GetPageFullName(SettingsForm.Placowka), KnownPage.Placowka),
            new KeyValuePair<string, KnownPage>(GetPageFullName(SettingsForm.RejestracjaTerminu), KnownPage.RejestracjaTerminu),
            new KeyValuePair<string, KnownPage>(GetPageFullName(SettingsForm.FormularzWiza_2), KnownPage.FormularzWiza_2)
        };

        private static string GetPageFullName(string page)
        {
            return Path.GetFullPath(Path.Combine("Pages", page));
        }

        private readonly HtmlDocumentConverter converter = new HtmlDocumentConverter();
        private Dictionary<KnownPage, PageSettings> pages = new Dictionary<KnownPage, PageSettings>();
        private int currentIndex = 0;
        private bool IsNewlyCreated = true;

        public SettingsForm()
        {
            InitializeComponent();
            this.webBrowser.DocumentCompleted += OnDocumentCompleted;
            this.AllowDrop = true;
          //  this.DragEnter += new DragEventHandler(SettingsForm_DragEnter);
          //  this.DragDrop += new DragEventHandler(SettingsForm_DragDrop);

        }

        //void SettingsForm_DragDrop(object sender, DragEventArgs e)
        //{
        //    var files = (string[])e.Data.GetData(DataFormats.FileDrop);
        //    ApplyDroppedFile(files.First());
        //}

        //private void ApplyDroppedFile(string file)
        //{
        //    try
        //    {
        //        var pageSettings = DifferentFileAdapter.ConvertToPageSetting(file);
        //        this.converter.CleanDocument(this.webBrowser.Document);
        //        this.converter.WriteSettings(this.webBrowser.Document, pageSettings);
        //    }
        //    catch
        //    {
        //        //skip bad files
        //    }
        //}
        
        //void SettingsForm_DragEnter(object sender, DragEventArgs e)
        //{
        //    if (PageNames[currentIndex].Value == KnownPage.FormularzWiza_2 && e.Data.GetDataPresent(DataFormats.FileDrop))
        //        e.Effect = DragDropEffects.Copy;
        //}

        void OnDocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            string page = Path.GetFileName(e.Url.ToString());
            if (this.IsKnownPage(e.Url) == false)
                this.SetupPage(0);

            else if (string.IsNullOrEmpty(page) == false)
            {
                this.webBrowser.AllowNavigation = false;
                KnownPage knownPage = SettingsForm.PageNames[this.currentIndex].Value;
                if (this.pages.ContainsKey(knownPage))
                {
                    PageSettings pageSet = this.pages[knownPage];
                    this.converter.WriteSettings(this.webBrowser.Document, pageSet);
                }
                if(knownPage == KnownPage.FormularzWiza_2 && this.IsNewlyCreated)
                    UpdateVisaStartDate();
            }
        }

        private void OnNextClick(object sender, EventArgs e)
        {
            this.SetupPage(this.currentIndex + 1);
        }

        private void OnBackClick(object sender, EventArgs e)
        {
            this.SetupPage(this.currentIndex - 1);
        }

        private void RefresfBrowser()
        {
            this.webBrowser.AllowNavigation = true;
            this.webBrowser.Url = new Uri("about:blank");
        }

        private bool SetupPage(int index)
        {
            if (this.IsKnownPage(this.webBrowser.Url))
            {
                if (index > this.currentIndex && this.IsValidPage() == false)
                {
                    this.SuspendLayout();
                    this.buttonNext.Visible = this.currentIndex < SettingsForm.PageNames.Length - 1;
                    this.buttonSave.Visible = this.currentIndex == SettingsForm.PageNames.Length - 1;
                    this.buttonBack.Enabled = this.currentIndex > 0;
                    this.ResumeLayout();
                    MessageBox.Show("Введены неправильные значения!!!", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return false;
                }
                KnownPage page = SettingsForm.PageNames[this.currentIndex].Value;
                PageSettings pageSet = this.converter.ReadSettings(this.webBrowser.Document);
                this.pages[page] = pageSet;
            }

            this.currentIndex = index;

            this.SuspendLayout();
            this.buttonNext.Visible = this.currentIndex < SettingsForm.PageNames.Length - 1;
            this.buttonSave.Visible = this.currentIndex == SettingsForm.PageNames.Length - 1;
            this.buttonBack.Enabled = this.currentIndex > 0;
            this.buttonClean.Visible = this.currentIndex == 3;
            this.ResumeLayout();

            this.webBrowser.AllowNavigation = true;
            this.webBrowser.Url = new Uri(SettingsForm.PageNames[this.currentIndex].Key);

            return true;
        }

        private void UpdateVisaStartDate()
        {
            var selectedRegistrationDate = this.pages[KnownPage.RejestracjaTerminu]["cbTermin"].InputValue;
            this.converter.InvokeScript(webBrowser.Document, "SetVisaStartDate", selectedRegistrationDate);
        }

        private bool IsKnownPage(Uri uri)
        {
            string url = Path.GetFullPath(uri.AbsolutePath);
            string pageName = Path.GetFileName(url);

            return pageName == Default
                || pageName == Placowka
                || pageName == RejestracjaTerminu
                || pageName == FormularzWiza_2;
        }

        private bool IsValidPage()
        {
            return Convert.ToBoolean(this.webBrowser.Document.InvokeScript("IsValid"));
        }

        private void OnOpenClick(object sender, EventArgs e)
        {
            DialogResult result = this.openFileDialog.ShowDialog();

            if (result == DialogResult.OK)
            {
                FormSettings userSet = null;
                DataContractSerializer serializer = new DataContractSerializer(typeof(FormSettings));
                using (Stream stream = File.OpenRead(this.openFileDialog.FileName))
                {
                    userSet = (FormSettings)serializer.ReadObject(stream);
                }
                this.pages.Clear();
                foreach (PageSettings pageSet in userSet.Pages)
                {
                    this.pages.Add((KnownPage)pageSet.ID, pageSet);
                }
                this.RefresfBrowser();
                this.IsNewlyCreated = false;
            }
        }

        private void OnSaveClick(object sender, EventArgs e)
        {
            if (this.IsKnownPage(this.webBrowser.Url))
            {
                if (this.IsValidPage())
                {
                    KnownPage page = SettingsForm.PageNames[this.currentIndex].Value;
                    PageSettings pageSet = this.converter.ReadSettings(this.webBrowser.Document);
                    this.pages[page] = pageSet;
                    this.Save();
                }
                else
                {
                    MessageBox.Show("Введены неправильные значения!!!", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }

        private void Save()
        {
            saveFileDialog.FileName = GetDefaultFileName();
            DialogResult result = saveFileDialog.ShowDialog();

            if (result == DialogResult.OK)
            {
                FormSettings userSet = new FormSettings();
                userSet.ID = this.GetHashCode();
                userSet.Name = this.GetHashCode().ToString();
                List<PageSettings> pageList = new List<PageSettings>();
                foreach (KnownPage page in SettingsForm.PageNames.Select(_ => _.Value))
                {
                    if (this.pages.ContainsKey(page))
                    {
                        pageList.Add(this.pages[page]);
                    }
                }
                pageList.Add(this.converter.GetPodsumowanieSettings());
                pageList.Add(this.converter.GetBledySettings());

                userSet.Pages = pageList.ToArray();

                DataContractSerializer serializer = new DataContractSerializer(typeof(FormSettings));
                using (Stream stream = File.Create(this.saveFileDialog.FileName))
                {
                    serializer.WriteObject(stream, userSet);
                }
            }
        }

        private void OnCleanClick(object sender, EventArgs e)
        {
            this.Clear();
        }

        private void Clear()
        {
            this.pages.Clear();
            this.RefresfBrowser();
            this.IsNewlyCreated = true;
        }


        private string GetDefaultFileName()
        {
            if (pages.ContainsKey(KnownPage.FormularzWiza_2))
            {
                FieldSettings lastname = pages[KnownPage.FormularzWiza_2].Fields.First(field => field.ElementID == "daneOs_txtNazwisko");
                FieldSettings firstname = pages[KnownPage.FormularzWiza_2].Fields.First(field => field.ElementID == "daneOs_txtImiona");

                return string.Format("{0}_{1}", firstname.InputValue, lastname.InputValue);
            }
            return Environment.UserName;
        }
    }
}
